/**
 * Created by Ysssssss on 20/12/14.
 */
import { COMPONENT_OPTIONS, TARGET_TYPE } from '../../../constants/common';
import { throttle } from '../../../common/debounce_throttle';
import { TipDialog } from '../../../common/tip';
import { tipToast } from '../../../common/env';
import { DEFAULT_GROUP_INFO } from '../../../constants/product';
import { getProductGroupList, getStoreProductGroupList } from '../../../api/product';

Component({
    behaviors: ['wx://component-export'],
    options: {
        ...COMPONENT_OPTIONS,
        pureDataPattern: /^_/, // 指定所有 _ 开头的数据字段为纯数据字段
    },
    properties: {
        type: {
            type: String,
            value: TARGET_TYPE.brand, // brand 品牌 | store 店铺
        },
        editMode: {
            type: Boolean,
            value: false,
        },
        activityGroupId: {
            type: Number,
            optionalTypes: [String],
            value: null,
        }
    },
    data: {
        movableGroupList: [],   // move-item 渲染数据
        draggingInfo: {},       // 当前item拖拽信息
        totalHeight: 0,
        _groupBoxSizeMap: {},  // move-item 尺寸
        _groupMovableWidth: 0,  // move-area 宽度
        _groupMargin: 10,       // move-item 间距
        editGroupInfo: null,
    },
    lifetimes: {
        ready: function () {
            this._getGroupList()
            this._moveChangeCalcThrottle = throttle(this._moveChangeCalc, 300).bind(this)
            this.groupEditRender = this._groupEditRender.bind(this)
            this.getGroupList = () => this.data.movableGroupList.map(group => ({
                productGroupId: group.productGroupId,
                name: group.name,
            }))
        },
    },
    methods: {
        async _getGroupList() {
            const { type } = this.data;
            let groupList = [];
            if (type === TARGET_TYPE.brand) {
                groupList = await getProductGroupList();
            } else if (type === TARGET_TYPE.store) {
                groupList = await getStoreProductGroupList();
            }
            this.setData({
                movableGroupList: groupList.concat(DEFAULT_GROUP_INFO),
            }, () => {
                this._calcAllGroupBoxPosition()
            })
        },
        // 更新触发重渲染
        _groupEditRender({ productGroupId, name }, type) {
            const { movableGroupList } = this.data
            switch (type) {
                case 'create':
                    this.setData({
                        movableGroupList: [
                            ...movableGroupList.slice(0, movableGroupList.length - 1),
                            {
                                productGroupId,
                                name
                            },
                            ...movableGroupList.slice(movableGroupList.length - 1), // '未分组'
                        ]
                    }, this._calcAllGroupBoxPosition)
                    break;
                case 'edit':
                    this.setData({
                        movableGroupList: movableGroupList.map(group => (group.productGroupId === productGroupId ? {
                            ...group,
                            name,
                        } : group)),
                        editGroupInfo: null
                    }, this._calcAllGroupBoxPosition)
                    break;
                case 'delete':
                    this.setData({
                        movableGroupList: movableGroupList.filter(group => group.productGroupId !== productGroupId)
                    }, this._calcAllGroupBoxPosition)
                    break;
                default:
                    break;
            }
        },

        // 初始化计算所有宽度
        _calcAllGroupBoxPosition() {
            const { movableGroupList, _groupMargin } = this.data
            const query = this.createSelectorQuery()
            query.select('#groupMovableView').boundingClientRect()
            query.selectAll('#groupMovableView .product-group-box').boundingClientRect()
            query.exec((res) => {
                let _groupMovableWidth = res[0].width
                const _groupBoxSizeMap = {}
                res[1].forEach(item => {
                    const productGroupId = item.dataset.id
                    _groupBoxSizeMap[productGroupId] = {
                        w: item.width,
                        h: item.height
                    }
                })
                let _movableGroupList = this._calcBoxItemPosition({
                    list: movableGroupList,
                    sizeMap: _groupBoxSizeMap,
                    margin: _groupMargin,
                    totalWidth: _groupMovableWidth
                })
                let lastGroup = _movableGroupList[_movableGroupList.length - 1]
                this.setData({
                    movableGroupList: _movableGroupList,
                    _groupBoxSizeMap,
                    _groupMovableWidth,
                    totalHeight: lastGroup.y + _groupBoxSizeMap[lastGroup.productGroupId].h + _groupMargin + 20
                })
            })
        },

        // 计算所有定位位置
        _calcBoxItemPosition({ list, sizeMap, margin, totalWidth }) {
            let _calcTotalWidth = 0
            let _calcTotalLine = 1
            return list.map(group => {
                let width = sizeMap[group.productGroupId].w
                let height = sizeMap[group.productGroupId].h
                let _pos = {
                    ...group,
                    x: _calcTotalWidth,
                    y: (_calcTotalLine - 1) * (height + margin) + margin
                }
                _calcTotalWidth = _calcTotalWidth + width + margin
                if (_calcTotalWidth > totalWidth) {
                    _calcTotalLine++
                    _calcTotalWidth = width + margin
                    _pos = {
                        ..._pos,
                        x: 0,
                        y: (_calcTotalLine - 1) * (height + margin) + margin
                    }
                }
                return _pos
            })
        },


        // 拖拽时确定排序顺序
        _moveChangeCalc(e) {
            const { movableGroupList, _groupMovableWidth, _groupBoxSizeMap, _groupMargin } = this.data
            let { x, y, source } = e.detail
            if (source === '' || source === 'out-of-bounds') return;
            if (source === 'touch-out-of-bounds' && y > 0 && x > 0) x = 9999
            if (y < 0) y = 0
            const productGroupId = e.currentTarget.dataset.id
            let targetInfo = {}
            let oldIndex = -1
            let newIndex = -1
            let _filteredMovableGroupList = movableGroupList.filter((group, index) => {
                if (group.productGroupId === productGroupId) {
                    oldIndex = index
                    targetInfo = {
                        ...group
                    }
                    return false
                }
                return true
            })
            for (let i = 1; i < _filteredMovableGroupList.length; i++) {
                let group = _filteredMovableGroupList[i]
                let size = _groupBoxSizeMap[group.productGroupId]
                let judgeWidth = group.x + size.w / 2
                let judgeHeight = group.y + size.h / 2
                if (group.y > y && i !== 1) {
                    newIndex = i
                    break;
                }
                if (x < judgeWidth && y < judgeHeight) {
                    newIndex = (x <= 0 && i === 1) ? 0 : i
                    break;
                }
            }
            if (newIndex < 0) newIndex = _filteredMovableGroupList.length - 1  // - 1 因为最后是未分组
            if (oldIndex !== newIndex) {
                let _movableGroupList = [
                    ..._filteredMovableGroupList.slice(0, newIndex),
                    targetInfo,
                    ..._filteredMovableGroupList.slice(newIndex),
                ]
                _movableGroupList = this._calcBoxItemPosition({
                    list: _movableGroupList,
                    sizeMap: _groupBoxSizeMap,
                    margin: _groupMargin,
                    totalWidth: _groupMovableWidth
                })
                this.setData({
                    movableGroupList: _movableGroupList,
                    draggingInfo: {
                        ...targetInfo,
                        x,
                        y
                    },
                })
            } else {
                this.setData({
                    draggingInfo: {
                        ...targetInfo,
                        x,
                        y
                    },
                })
            }
        },
        handleMoveChange(e) {
            this._moveChangeCalcThrottle(e)
        },
        handleTouchend(e) {
            const { draggingInfo } = this.data
            if (draggingInfo.productGroupId) {
                this.setData({
                    draggingInfo: {}
                })
            }
        },
        handleLongPress(e) {
            const productGroupId = e.currentTarget.dataset.id
            this.setData({
                draggingInfo: {
                    productGroupId
                }
            })
        },
        handleTap(e) {
            const { movableGroupList, editMode } = this.data
            const { index } = e.currentTarget.dataset
            let groupInfo = movableGroupList[index]
            if (editMode) {
                this.setData({
                    editGroupInfo: {
                        ...groupInfo
                    }
                })
            } else {
                this.triggerEvent('groupTap', groupInfo)
            }
        },
        handleDelete(e) {
            const { movableGroupList, editMode } = this.data
            const { index } = e.currentTarget.dataset
            let groupInfo = movableGroupList[index]
            const _ = this;
            TipDialog({
                title: `是否删除“${groupInfo.name}”？`,
                message: '确定删除后，该分组下的商品将被置为“未分组”',
                ok: () => {
                    _.triggerEvent('groupEdit', {
                        productGroupId: groupInfo.productGroupId,
                        type: 'delete',
                    })
                }
            })
        },
        // 编辑弹窗confirm
        editGroup(e) {
            const { editGroupInfo } = this.data
            const value = e.detail
            setTimeout(() => {
                if (value) {
                    this.triggerEvent('groupEdit', {
                        productGroupId: editGroupInfo.productGroupId,
                        name: value,
                        type: 'edit',
                    })
                } else {
                    tipToast('请输入分组名称')
                }
            }, 1000)
        },
        // 编辑弹窗close
        closeEditModal(e) {
            if (e.detail !== 'confirm') {
                this.setData({
                    editGroupInfo: null
                })
            }
        },
    }
})